Skip to content
This repository has been archived by the owner on Apr 13, 2019. It is now read-only.

Support loading binary files in addition to ELF files #175

Open
wants to merge 1 commit into
base: qemu-for-testing
Choose a base branch
from

Conversation

lukasauer
Copy link

The kernel and bootloader are not always available as ELF files, or
directly executable. For example, the kernel might be included together
with a device tree inside of an image. Support this use case by adding
support for loading binary files in addition to ELF files.

With this patch, the files specified with the -bios and -kernel
parameters are attempted to be loaded as ELF files first. If this fails,
they are loaded directly to memory instead.

lukasauer added a commit to lukasauer/u-boot that referenced this pull request Oct 19, 2018
QEMU embeds the location of the kernel image in the device tree. Store
this address in the environment as variable kernel_start and use it in
CONFIG_BOOTCOMMAND to boot the kernel.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Series-to: u-boot
Series-cc: bmeng
Cover-letter:
General fixes / cleanup for RISC-V and improvements to qemu-riscv

This patch series includes general fixes and cleanup for RISC-V. It also
adds support for booting Linux on qemu-riscv. At the moment, only
single-core systems are supported. Support for multi-core systems will
be added with a future patch series.

To boot Linux on qemu-riscv, Linux must be compiled into BBL as a
payload. BBL must be included in a FIT image and supplied to QEMU with
the -kernel parameter. Its location in memory is embedded in the device
tree, which QEMU passes to u-boot.
To test this, QEMU and riscv-pk (BBL) must be modified. QEMU is modified
to add support for loading binary files (FIT images in this case) in
addition to ELF files. riscv-pk must be modified to adjust the link
address and to ignore the kernel address from the device tree. A pull
request for QEMU, which implements this, is available at [1]. A modified
version of riscv-pk is available at [2].

[1]: riscvarchive/riscv-qemu#175
[2]: https://github.com/lukasauer/riscv-pk/tree/riscv-u-boot
END
@lukasauer
Copy link
Author

Ping?
The Travis CI failures seem to be unrelated to my patch.

hw/riscv/boot.c Outdated
@@ -46,15 +46,25 @@ static uint64_t kernel_translate(void *opaque, uint64_t addr)
}
}

hwaddr riscv_load_firmware(const char *filename)
hwaddr riscv_load_firmware(const char *filename, hwaddr ram_start,
uint64_t ram_size)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should avoid requiring "ram_size", It possible there may be configurations with discontiguous memories and this is incompatible with that. We spent a bit of effort to removing hardcoding of assumptions with respect to memory from core code. Hopefully, it doesn't creep back in.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was not aware of that. I will update the patch to remove ram_size.

hw/riscv/boot.c Outdated
firmware_entry = ram_start;
firmware_start = ram_start;

size = load_image_targphys(filename, firmware_start, ram_size);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, the size on load_image_targphys is the maximum firmware size so we could perhaps add a constant for maximum firmware size. This simplifies the patch as the we no longer have to make assumptions about memory type, however it would add a maximum limit on the firmware size. I think the latter is reasonable. There is a firmware size limit on the HiFive Unleashed iirc. Perhaps some suitable value base on the size of a reasonable kernel and ramdisk.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QEMU ROM routines won't overwrite past the end of the memory regions so it doesn't matter too much what the limit is.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. Since we won't have a problem with overwriting past memory regions, how about 2 GB to fill the complete address range of RV32I systems?

hw/riscv/boot.c Outdated
@@ -71,15 +81,31 @@ hwaddr riscv_load_firmware(const char *filename)
return firmware_entry;
}

hwaddr riscv_load_kernel(const char *filename, void *fdt)
hwaddr riscv_load_kernel(const char *filename, void *fdt, hwaddr ram_start,
uint64_t ram_size)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto wrt ram_size

void riscv_load_initrd(const char *filename, uint64_t mem_size,
hwaddr firmware_entry, void *fdt);
hwaddr riscv_load_firmware_kernel_initrd(MachineState *machine, void *fdt);
hwaddr riscv_load_firmware_kernel_initrd(MachineState *machine, void *fdt,
hwaddr ram_start);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bulk of the patch seems to be plumbing through ram_size. The actual change is pretty small after this unnecessary plumbing is removed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your review!

That's true, but I will still need to add ram_start here.

The kernel and bootloader are not always available as ELF files, or
directly executable. For example, the kernel might be included together
with a device tree inside of an image. Support this use case by allowing
binary files to be loaded in addition to ELF files.

With this patch, the files specified with the -bios and -kernel
parameters are attempted to be loaded as ELF files first. If this fails,
they are loaded directly to memory instead.

The binary size is limited to 2 GiB to stay within the 32-bit address
space and ensure compatibility with both RV32I and RV64I.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
@lukasauer
Copy link
Author

I have updated my patch with your comments. Please let me know if it looks good to you now.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants